package ks.client.kommander;

import java.util.Hashtable;

/**
 * Kommander - "You know what the chain of command is? It's the chain I go get 
 *              and beat you with 'til you understand who's in ruttin' command 
 *              here!" - Jayne Cobb
 * 
 * The Kommander Class is for storing code to be executed on the receipt of an
 * ack and/or nack sent by the server in response to a command send with a 
 * certain unique id (the id attribute of the command or admin-command 
 * element).
 * 
 * Note: You will need to add code to call the runAck(...) and runNack(...) 
 *       methods in your client-side Message Processor.
 * 
 * @author Christopher Page
 */
public class Kommander {
	
	/**
	 * Stores the Action containing the code to be executed as the value 
	 * corresponding to the key. The key consists of the unique id of the
	 * command/admin-command sent to the server.
	 */
	private Hashtable<String, Action> actions;
	
	/**
	 * Stores the next unique id to give out upon request.
	 */
	private long uid;
	
	/**
	 * The constructor. Instantiates the actions Hashtable and sets the uid 
	 * counter to 0.
	 */
	public Kommander () {
		actions = new Hashtable<String, Action>();
		uid = 0;
	}
	
	/**
	 * Retrieves a new unique id. Note: eventually the uid counter will 
	 * overflow and eventually give you previously given values. Therefore, 
	 * this is not 100% guaranteed to be unique (over many uses), but it 
	 * should be suitable enough.
	 * 
	 * @return A String representing the new unique id.
	 */
	public String generateUid() {
		uid++;
		return String.valueOf(uid-1);
	}
	
	/**
	 * Stores the provided Action to be run when an ack and/or nack is 
	 * received for the command/admin-command with the given id.
	 * 
	 * @see #ks.client.kommander.Action
	 * 
	 * @param id The unique id of the command/admin-command sent to the server.
	 * @param action The Action to be executed upon receipt of an ack or nack.
	 */
	public void addAction(String id, Action action) {
		actions.put(id, action);
	}
	
	/**
	 * Runs the ack code in the Action related to the given id.
	 * 
	 * @param id The id of the ack request.
	 */
	public void runAckAction(String id) {
		Action action = actions.get(id);
		if (action != null) {
			actions.get(id).ack();
			actions.remove(id);
		}
	}
	
	/**
	 * Runs the nack code in the Action related to the given id.
	 * 
	 * @param id The id of the nack request.
	 */
	public void runNackAction(String id) {
		Action action = actions.get(id);
		if (action != null) {
			actions.get(id).nack();
			actions.remove(id);
		}
	}
}
